#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;

#define MAXN 100+5

struct edge {
	int u, v, c;
	edge(): u(-1), v(-1), c(0) { }
	edge(int u, int v, int c): u(u), v(v), c(c) { }
};

struct edge_greater {
	bool operator()(edge &lhs, edge &rhs) {
		return (lhs.c > rhs.c);
	}
};

int N;

int main() {
	while (~scanf("%d", &N)) {
		priority_queue<edge, vector<edge>, edge_greater> E;
		for (int i=1; i<=N; i++) {
			for (int j=1; j<=N; j++) {
				int c;
				scanf("%d", &c);
				E.push(edge(i, j, c));
			}
		}
		//Kruskal
		int cnt = 0;
		int sum = 0;
		int FL[MAXN];
		for (int i=1; i<=N; i++) {
			FL[i] = i;
		}
		while (!E.empty()) {
			edge e = E.top(); E.pop();
			if (cnt >= N) break;
			if (FL[e.u] == FL[e.v]) continue;
			cnt++;
			sum += e.c;
			int fleu = FL[e.u];
			int flev = FL[e.v];
			for (int i=1; i<=N; i++) {
				if (FL[i] == flev) {
					FL[i] = fleu;
				}
			}
		}
		printf("%d\n", sum);
	}
	return 0;
}
